4.2.1 js数组全排列
递归实现js数组全排列
当n = 1时, 数组arr = [A],全排列结果为 [A];
当n = 2时, 数组arr = [A, B],全排列结果为 [A, B] [B, A];
当n = 3时, 数组arr = [A, B, C],全排列结果为
[A, B, C]
[A, C, B]
[B, A, C]
[B, C, A]
[C, A, B]
[C, B, A]
1
2
3
4
5
6
2
3
4
5
6
到n = 3时可以看出全排列有以下规律:
- 1.固定第一个元素,将剩下的元素进行全排列处理;
- 2.将第一个元素与依次与第i(1<i<=arr.length)个元素互换,将剩下的元素进行全排列处理;
很适合使用递归解决。只要写一个全排列函数permutation,能固定一个下标为i的元素,剩下元素再进行全排列即可。
ES5中使用闭包将全排列函数封装。
// 数组全排列
function Permutation(arr) {
this.len = 0; // 存储全排列次数
this.arr = arr.concat(); // 传入的数组
this.result = []; // 存储全排列结果
// 首次创建对象时初始化方法
if (typeof Permutation.run == 'undefined') {
Permutation.prototype.start = function() {
this.run(0);
}
// 递归函数(核心方法),index为数组下标
Permutation.prototype.run = function(index) {
// 单遍历到数组末端时,将结果储存在result数组中,全排列次数加1
if (index == this.arr.length - 1) {
this.result.push(this.arr.slice());
this.len++;
return;
}
for(let i = index; i < this.arr.length; i++) {
this.swap(this.arr, index, i); // 与下标为i的元素交换位置
this.run(index + 1); // 剩下元素全排列
this.swap(this.arr, index, i); // 复原数组
}
}
// 交换位置
Permutation.prototype.swap = function(array, i, j) {
var t;
t = array[i];
array[i] = array[j];
array[j] = t;
}
}
}
var per = new Permutation(['A', 'B', 'C']);
per.start();
console.log(per.result);
console.log(per.len);
// [ [ 'A', 'B', 'C' ],
// [ 'A', 'C', 'B' ],
// [ 'B', 'A', 'C' ],
// [ 'B', 'C', 'A' ],
// [ 'C', 'B', 'A' ],
// [ 'C', 'A', 'B' ] ]
// 6
ES5代码使用动态原型模式创建对象,主要是想让函数封装的尽量像一个类。在ES6中有class,语法可以更加简洁高效。
// ES6
class Permutation {
constructor(arr) {
this.arr = Array.from(arr);
this.result = [];
this.len = 0;
this.run(0);
}
run(index) {
if (index == this.arr.length - 1) {
this.result.push(Array.from(this.arr));
this.len++;
return;
}
for(let i = index; i < this.arr.length; i++) {
[this.arr[index], this.arr[i]] = [this.arr[i], this.arr[index]];
this.run(index + 1);
[this.arr[index], this.arr[i]] = [this.arr[i], this.arr[index]];
}
}
}
let p = new Permutation(["A", "B", "C"]);
console.log(p.result);
console.log(p.len);
// [ [ 'A', 'B', 'C' ],
// [ 'A', 'C', 'B' ],
// [ 'B', 'A', 'C' ],
// [ 'B', 'C', 'A' ],
// [ 'C', 'B', 'A' ],
// [ 'C', 'A', 'B' ] ]
// 6
以上就是全排列的js实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
全排列另一个写法(可能好理解一些)
function permutation(arr){
if (arr.length == 1)
return arr;
else if (arr.length == 2)
return [[arr[0],arr[1]],[arr[1],arr[0]]];
else {
var temp = [];
for (var i = 0; i < arr.length; i++) {
var save = arr[i];
arr.splice(i, 1);//取出arr[i]
var res = permutation(arr);//递归排列arr[0],arr[1],...,arr[i-1],arr[i+1],...,arr[n]
arr.splice(i, 0, save);//将arr[j]放入数组,保持原来的位置
for (var j = 0; j < res.length; j++) {
res[j].push(arr[i]);
temp.push(res[j]);//将arr[j]组合起来
}
}
return temp;
}
}
---------------------
作者:筱葭
原文:https://blog.csdn.net/zhouziyu2011/article/details/62237216
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24